package com.heisenhub.common.oauth.hander;

import com.heisenhub.common.oauth.annotation.ApiResourceOpen;
import com.heisenhub.common.oauth.enums.RESTAPI;
import com.heisnenhub.common.module.utils.GsonUtils;
import com.heisnenhub.common.module.utils.HubObjectUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.reflections.Reflections;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Primary;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.mvc.condition.PathPatternsRequestCondition;
import org.springframework.web.servlet.mvc.condition.PatternsRequestCondition;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
import org.springframework.web.util.pattern.PathPattern;

import java.lang.reflect.Method;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author sen
 * @description
 * @date 2023/12/29 16:35
 */
@Slf4j
public class ApiResourceOpenHander {

    // 添加缓存Map
    public final static Map<RESTAPI, String[]> apiPathCache = new ConcurrentHashMap<>();
    public String[] handle(ApplicationContext applicationContext ,RESTAPI restapi){

        // 先从缓存中获取
        String[] cachedPaths = apiPathCache.get(restapi);
        if (cachedPaths != null) {
            return cachedPaths;
        }

        Map<RequestMappingInfo, HandlerMethod> handlerMethodMap = applicationContext.getBean("requestMappingHandlerMapping",RequestMappingHandlerMapping.class).getHandlerMethods();
        Set<String> apiurls = new HashSet<>();
        for (Map.Entry<RequestMappingInfo, HandlerMethod> infoEntry : handlerMethodMap.entrySet()) {
            HandlerMethod handlerMethod = infoEntry.getValue();
            ApiResourceOpen apiResourceOpen = handlerMethod.getMethodAnnotation(ApiResourceOpen.class);
            if (apiResourceOpen !=null && restapi.equals(apiResourceOpen.value()) ) {
                RequestMappingInfo key = infoEntry.getKey();
                PathPatternsRequestCondition pathPatternsCondition = key.getPathPatternsCondition();
                Set<String> patternValues = pathPatternsCondition.getPatternValues();
                apiurls.addAll(patternValues);
            }
        }
        log.info("【{} 放行路径】 {}",restapi,GsonUtils.toJson(apiurls));
        String[] result;
        if(!CollectionUtils.isEmpty(apiurls)) {
            result = apiurls.toArray(new String[0]);
        } else {
            result = new String[0];
        }

        // 将结果存入缓存
        apiPathCache.put(restapi, result);

        return result;
    }


    // 提供清除缓存的方法
    public void clearCache() {
        apiPathCache.clear();
    }

    // 提供清除特定RESTAPI缓存的方法
    public void clearCache(RESTAPI restapi) {
        apiPathCache.remove(restapi);
    }

    // 获取缓存状态
    public Map<RESTAPI, String[]> getCacheStatus() {
        return new HashMap<>(apiPathCache);
    }



}